package com.leyou.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.dto.PageDTO;
import com.leyou.entity.Brand;
import com.leyou.dto.BrandDTO;
import com.leyou.entity.CategoryBrand;
import com.leyou.mapper.BrandMapper;
import com.leyou.service.BrandService;
import com.leyou.service.CategoryBrandService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;


//todo brand的实现类
public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements BrandService {


    @Override
    public PageDTO<BrandDTO> queryBrandByPage(Integer page, Integer rows, String key) {
        //分页信息的健壮性处理
        page=Math.min(page,100);
        rows=Math.max(rows,5);
        //构建分页条件
        Page<Brand> iPage = new Page<>(page, rows);
        //判断key是否存在
        Boolean condition= StringUtils.isNotBlank(key);
        //分页查询时包含条件查询
        page(iPage,new QueryWrapper<Brand>().like(condition,"name",key)
                .or()
                .eq(condition,"letter",key));
        //根据查询结果，封装分页响应结果，:::返回的是brandDTO集合，所以要做好转换
        return new PageDTO<>(iPage.getTotal(),iPage.getPages(),
                BrandDTO.convertEntityList(iPage.getRecords()));
    }

    @Override
    public List<BrandDTO> queryBrandByCategory(Long cid) {
        return null;
    }

    @Override
    public BrandDTO queryBrandById(Long bid) {
        return null;
    }

   /*
TODO    添加品牌，
    在新增品牌的同时还需要新增一张中间表，需要对新增的数进行分类

    */

    /*
todo 使用构造器注入的好处：
         保证依赖不可变（final关键字）
         保证依赖不为空（省去了我们对其检查）
         保证返回客户端（调用）的代码的时候是完全初始化的状态
         避免了循环依赖
         提升了代码的可复用性
      另外，当有一个依赖有多个实现的使用，推荐使用field注入或者setter注入的方式来指定注入的类型
* */
    @Autowired
    private final CategoryBrandService categoryBrandService;

    public BrandServiceImpl(CategoryBrandService categoryBrandService){
    this.categoryBrandService=categoryBrandService;
     }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addBrand(BrandDTO brandDTO,List<Long> cids) {
        //先保存品牌
        Brand brand = brandDTO.toEntity(Brand.class);
//        //先保品牌，主键回显
        if (this.save(brand)){
            //根据传入的分类集合，以及品牌id，构建中间表对象集合
            saveCategoryBrand(cids,brand.getId());
        }
        //方式二
      //保存brand新增的数据
//        save(brand);
//        //封装中间表对象集合
//        brandDTO.getCategoryIds().stream().map(id-> CategoryBrand.of(id,brand.getId()))
//                .collect(Collectors.toList());
    }


    //中间表保存逻辑
    private void saveCategoryBrand(List<Long>cids,Long bid){
        List<CategoryBrand>categoryBrands=cids.stream().map(cid->CategoryBrand
                .of(cid,bid))
                .collect(Collectors.toList());
        this.categoryBrandService.saveBatch(categoryBrands);
    }


    //品牌修改
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBrand(BrandDTO brandDTO, List<Long> cids) {
        //将新添加的数据复制到要修改的地方
        Brand brand = brandDTO.toEntity(Brand.class);
        //如果品牌修改成功，则去操作中间表
        if (this.updateById(brand)){
            //中间逻辑的删除
            this.categoryBrandService.remove(new QueryWrapper<CategoryBrand>()
                    .eq("brand_id",brand.getId()));
            //重建中间表逻辑
            saveCategoryBrand(cids,brand.getId());
        }

    }

    //根据id删除品牌
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBrandById(BrandDTO brandDTO, Long bids) {
        //删除中间表
        this.categoryBrandService.remove(new QueryWrapper<CategoryBrand>()
                .eq("brand_id",bids));
    }
}
